package com.example.script.admin.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.*;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spi.service.contexts.SecurityContext;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

import java.util.ArrayList;
import java.util.List;

@Configuration
@EnableSwagger2
public class AdminSwagger2Config {
        /**
         * 注册Swagger Bean对象到spring容器
         *
         * @return Docket 对象
         */
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .select()
                    .apis(RequestHandlerSelectors.basePackage("com.example.script.admin.controller"))
                    .paths(PathSelectors.any())
                    .build()
                    .securitySchemes(securitySchemes())
                    .securityContexts(securityContexts());
        }

        /**
         * 设置Swagger页面的摘要信息
         *
         * @return ApiInfo对象（摘要信息）
         */
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    .title("script剧本杀预约前台模块")
                    .description("script剧本杀预约前台模块")
                    .contact(new Contact("example-script", "https://www.qingmengtech.com", ""))
                    .version("1.1")
                    .build();
        }

        /**
         * 配置Swagger2的安全模式，这里指定token通过Authorization头请求头传递
         *
         * @return ApiKey列表
         */
        private List<ApiKey> securitySchemes() {
            // 设置请求头信息
            List<ApiKey> result = new ArrayList<>();
            ApiKey apiKey = new ApiKey("Authorization", "Authorization", "header");
            result.add(apiKey);
            return result;
        }

        /**
         * 安全上下文
         * <p>
         * 通过正则表达式设置使用参数的接口（或者说是去除掉不需要使用参数的接口）
         *
         * @return SecurityContext对象列表
         */
        private List<SecurityContext> securityContexts() {
            // 设置需要登录认证的路径
            List<SecurityContext> result = new ArrayList<>();
            result.add(getContextByPath("/user/.*"));
            result.add(getContextByPath("/project/.*"));
            result.add(getContextByPath("/projectSchedule/.*"));
            result.add(getContextByPath("/teamAmount/.*"));
            result.add(getContextByPath("/turnover/.*"));
            result.add(getContextByPath("/invite/.*"));
            result.add(getContextByPath("/receipt/.*"));
            result.add(getContextByPath("/admin/.*"));

            return result;
        }

        /**
         * 根据路径字符串创建SecurityContext对象
         *
         * @param pathRegex 路径参数
         * @return SecurityContext对象
         */
        private SecurityContext getContextByPath(String pathRegex) {
            return SecurityContext.builder()
                    .securityReferences(defaultAuth())
                    .forPaths(PathSelectors.regex(pathRegex))
                    .build();
        }

        /**
         * 默认的安全引用
         *
         * @return SecurityReference列表
         */
        private List<SecurityReference> defaultAuth() {
            List<SecurityReference> result = new ArrayList<>();
            AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything");
            AuthorizationScope[] authorizationScopes = new AuthorizationScope[1];
            authorizationScopes[0] = authorizationScope;
            result.add(new SecurityReference("Authorization", authorizationScopes));
            return result;
        }
    }
